<template>
  <el-aside style="width: 225px">
    <el-input v-model="filterCategory" :placeholder="t('resources.category.filter')" width="100%" />
    <el-tree
      ref="categoryDataRef"
      :data="categoryData"
      default-expand-all
      highlight-current
      @node-click="categorySelect"
      :props="props"
      :filter-node-method="filterNode"
      style="width: 100%; height: calc(100% - 90px); margin-top: 15px"
    >
      <template #default="{ node, data }">
        <span class="container">
          <span>{{ node.label }}</span>
          <span class="fixed-span">
            <el-icon @click="append(data, $event)" size="15px" style="margin-right: 5px"><Plus /></el-icon>
            <el-icon @click="remove(node, $event)" size="15px" style="margin-right: 5px"><Delete /></el-icon>
          </span>
        </span>
      </template>
    </el-tree>
    <el-button type="primary" plain style="width: 90%" round v-if="pagination.total > categoryData.length">Primary</el-button>
  </el-aside>

  <el-dialog v-model="addCategoryVisible" align-center destroy-on-close :close-on-click-modal="false">
    <template #header> {{ $t("resources.category.create_title") }} </template>
    <el-form ref="categoryFormRef" :model="ruleForm" :rules="rules" label-width="140px">
      <el-form-item :label="t('resources.category.name')" prop="name">
        <el-input v-model="ruleForm.name" />
      </el-form-item>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="addCategoryVisible = false">{{ $t("common.cancel") }}</el-button>
        <el-button type="primary" @click="saveCategory(categoryFormRef)"> {{ $t("common.save") }} </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup name="Category">
import { ref, reactive, onBeforeMount, watch, onBeforeUnmount } from "vue";
import { ElTree, FormInstance } from "element-plus";
import { ResourceCategoryList, ResourceCategoryCreate, ResourceCategoryDel } from "@/api/modules/common";
import { useI18n } from "vue-i18n";

const { t } = useI18n();
const categoryData = ref([{ id: 0, name: "全部" }]);
const props = {
  label: "name"
};

const pagination = reactive({
  total: 0,
  page: 0
});

const nextTreeLoad = () => {
  const params = {
    page: pagination.page + 1
  };

  reuqestCategoryList(params).then(response => {
    response.data.list.forEach(item => {
      categoryData.value.push(item);
    });

    // categoryData.value = [...categoryData.value, ...response.data.list];
    pagination.total = response.data.total;
    pagination.page = response.data.page;
  });
};

onBeforeMount(() => {
  nextTreeLoad();
});

const reuqestCategoryList = (params?: object) => {
  return ResourceCategoryList(params);
};

const categoryDataRef = ref<InstanceType<typeof ElTree>>();
const filterCategory = ref("");
watch(filterCategory, val => {
  categoryDataRef.value!.filter(val);
});

const filterNode = (value: string, data: Tree) => {
  if (!value) return true;
  return data.name.includes(value);
};

const addCategoryVisible = ref(false);

const ruleForm = reactive({
  parent_id: 0,
  name: "",
  data: []
});

const append = (data, event) => {
  event.stopPropagation(); // 阻止事件向父元素传播
  event.preventDefault(); // 阻止浏览器默认行为
  ruleForm.parent_id = data.id;
  ruleForm.name = "";
  ruleForm.data = data;
  addCategoryVisible.value = true;
};

const rules = {
  name: [{ required: true, message: t("resources.category.name_msg"), trigger: "blur" }]
};

const categoryFormRef = ref();
const saveCategory = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate(valid => {
    if (valid) {
      ResourceCategoryCreate(ruleForm).then(response => {
        if (response.code == 200) {
          if (!ruleForm.data.children) {
            ruleForm.data.children = [];
          }

          if (ruleForm.parent_id) {
            ruleForm.data.children.push(response.data);
            categoryData.value = [...categoryData.value];
          } else {
            categoryData.value.push(response.data);
          }

          ruleForm.parent_id = 0;
          ruleForm.name = "";
          ruleForm.data = [];
          addCategoryVisible.value = false;
          ElMessage.success(response.message);
        } else {
          ElMessage.error(response.message);
        }
      });
    } else {
      ElMessage.error(t("common.form_check_error"));
    }
  });
};

const emit = defineEmits(["setCategoryId"]);

const categorySelect = node => {
  emit("setCategoryId", node.id > 0 ? node.id : "");
  if (node.id > 0 && node.count > 0) {
    if (!node.children) {
      node.children = [];
    }

    reuqestCategoryList({
      parent_id: node.id,
      limit: 50
    }).then(response => {
      response.data.list.forEach(item => {
        node.children.push(item);
        node.count--;
      });

      categoryData.value = [...categoryData.value];
    });
  }
};

const remove = (node, event) => {
  event.stopPropagation(); // 阻止事件向父元素传播
  event.preventDefault(); // 阻止浏览器默认行为
  if (node.data.id == 0) {
    return;
  }

  ResourceCategoryDel({ id: node.data.id }).then(response => {
    if (response.code == 200) {
      const data = node.data;
      const parent = node.parent;
      const children = parent.data.children || parent.data;
      const index = children.findIndex(d => d.id === data.id);
      children.splice(index, 1);
      categoryData.value = [...categoryData.value];
    }
  });
};

onBeforeUnmount(() => {
  emit("setCategoryId", "");
});
</script>

<style scoped lang="scss">
.container {
  position: relative;
  width: calc(100% - 2px);
}
.fixed-span {
  position: absolute;
  right: 0;
}
</style>
